package com.example.order.config;

import feign.Logger;
import feign.RetryableException;
import feign.Retryer;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OrderServiceConfig {

    /**
     * RestTemplate 是 Spring 提供的同步 HTTP 客户端工具类，用于向 RESTful Web 服务发送请求、接收响应。
     * @LoadBalanced 表示启用 Spring Cloud LoadBalancer，允许使用 http://服务名 调用服务。
     */
    @Bean
    @LoadBalanced // 注解式负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    /**
     * 你可以为每个客户端配置 Logger.Level 对象，告诉 Feign 要记录多少内容。选择是：
     * NONE, 没日志（默认）。
     * BASIC, 只记录请求方法和URL以及响应状态代码和执行时间。
     * HEADERS, 记录基本信息以及请求和响应头。
     * FULL, 记录请求和响应的header、正文和元数据。
     */
    /**
     * Spring Boot启动时，加载顺序是：
     * 先加载Java配置（@Configuration、@Bean）
     * 后加载外部配置文件（application.yml、application.properties）
     * 外部配置可以覆盖内部@Bean定义的内容，这符合SpringBoot的设计哲学：
     * “约定优于配置，配置优于编码。”
     * 所以如果你两边都配了：
     * 启动时还是以 application.yml 中的 spring.cloud.openfeign.client.config配置为准！
     *
     * @Bean Logger.Level会被覆盖掉。
     * @Bean Logger.Level 和 application.yml的spring.cloud.openfeign.client.config都是为了配置Feign日志级别，一般只用application.yml即可，优先级高、灵活性强。
     */
//    @Bean
//    Logger.Level feignLoggerLevel() {
//        return Logger.Level.FULL;
//    }

    /**
     * Spring Cloud OpenFeign 默认不为 feign 提供以下Bean，但仍然从 application context 查找这些类型的 Bean 来创建 feign 客户端：
     * Logger.Level
     * Retryer
     * ErrorDecoder
     * Request.Options
     * Collection<RequestInterceptor>
     * SetterFactory
     * QueryMapEncoder
     * Capability (MicrometerObservationCapability 和 CachingCapability 默认提供)
     * 默认情况下，会创建一个 Retryer.NEVER_RETRY 类型的 Retryer bean，它将禁用重试。
     * 注意这个重试行为与 Feign 的默认行为不同，它将自动重试 IOExceptions，将其视为瞬时网络相关的异常，以及从 ErrorDecoder 抛出的任何 RetryableException。
     */
    /**
     * 你通过@Bean直接生成了一个Retryer对象（默认构造，100ms起步，最多5次）。
     * Spring Boot启动时，Feign模块发现容器里已经有了一个Retryer Bean。
     * Spring就直接用你的这个Retryer对象来做重试控制。
     * application.yml里如果有关于feign.client.config.default.retryer的配置？也没用了！不会去覆盖你@Bean返回的Retryer！
     * ✅ 你的@Bean配置 > application.yml的配置
     */
    /**
     * OpenFeign的重试机制
     */
//    @Bean
//    Retryer retryer() {
//        return new Retryer.Default(100L, 1600L, 8);
//    }

}